<template>
  <div></div>
</template>
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'
import { WebGPURenderer, PostProcessing } from 'three/webgpu'
import { pass, uniform, time, oscSine,mrt, output, emissive, renderOutput } from 'three/tsl'
import { outline } from 'three/addons/tsl/display/OutlineNode.js'
import { bloom } from 'three/addons/tsl/display/BloomNode.js';
import { fxaa } from 'three/addons/tsl/display/FXAANode.js';
import { onMounted, reactive } from 'vue'
let renderer = reactive()
let scene = reactive()
let camera = reactive()
let outlinePass = reactive()
let postProcess = reactive()
let gltf = reactive()
let selectedObjects = reactive([])
let rayCaster = reactive()
let mouse = reactive()
onMounted(async () => {
  scene = new THREE.Scene()
  const loader2 = new GLTFLoader()
  gltf = await loader2.loadAsync('gltf/玻璃.gltf')
  scene.add(gltf.scene)
  // renderer = new THREE.WebGLRenderer()
  renderer = new WebGPURenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setAnimationLoop(animate)
  renderer.domElement.style.touchAction = 'none'
  renderer.domElement.addEventListener('pointermove', onPointerMove)
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  document.body.appendChild(renderer.domElement)
  rayCaster = new THREE.Raycaster()
  mouse = new THREE.Vector2()
  // const geometry = new THREE.BoxGeometry(1, 1, 1)
  // const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
  // const cube = new THREE.Mesh(geometry, material)
  // scene.add(cube)

  const RGBE = await new RGBELoader()
    .setPath('equirectangular/')
    .loadAsync('royal_esplanade_1k.hdr')
  RGBE.mapping = THREE.EquirectangularReflectionMapping
  scene.background = RGBE
  scene.environment = RGBE

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.set(100, 0, 100)

  const controls = new OrbitControls(camera, renderer.domElement)
  controls.update()

  const material = new THREE.MeshStandardMaterial({
    color: 0xffffff, // 表面颜色
    emissive: 0xffffff // 自发光颜色
  });

// 创建一个几何体并应用材质
  const geometry = new THREE.BoxGeometry(10, 10, 10);
  const cube = new THREE.Mesh(geometry, material);
  cube.position.set(0, 40, 0)

// 将立方体添加到场景中
  scene.add(cube);


  outlineFu()
  animate()
})
const onPointerMove = (event) => {
  if (event.isPrimary === false) return

  mouse.x = (event.clientX / window.innerWidth) * 2 - 1
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1

  checkIntersection()
}

const checkIntersection = () => {
  rayCaster.setFromCamera(mouse, camera)

  const intersects = rayCaster.intersectObject(scene, true)

  if (intersects.length > 0) {
    // addSelectedObject( selectedObject );
    outlinePass.selectedObjects = [intersects[0].object.parent]
  } else {
    outlinePass.selectedObjects = []
  }
}

const outlineFu = () => {
  // outline pass

  const edgeStrength = uniform(3.0)
  const edgeGlow = uniform(0.0)
  const edgeThickness = uniform(1.0)
  const pulsePeriod = uniform(0)
  const visibleEdgeColor = uniform(new THREE.Color(0xffffff))
  const hiddenEdgeColor = uniform(new THREE.Color(0x4e3636))

  outlinePass = outline(scene, camera, {
    selectedObjects,
    edgeGlow,
    edgeThickness,
  })

  const { visibleEdge, hiddenEdge } = outlinePass

  const period = time.div(pulsePeriod).mul(2)
  const osc = oscSine(period).mul(0.5).add(0.5) // osc [ 0.5, 1.0 ]

  const outlineColor = visibleEdge
    .mul(visibleEdgeColor)
    .add(hiddenEdge.mul(hiddenEdgeColor))
    .mul(edgeStrength)
  const outlinePulse = pulsePeriod.greaterThan(0).select(outlineColor.mul(osc), outlineColor)

  // postprocessing

  const scenePass = pass(scene, camera)

  scenePass.setMRT( mrt( {
    output,
    emissive
  } ) );

  const outputPassFAXX = renderOutput( scenePass );

  const outputPass = scenePass.getTextureNode();
  const emissivePass = scenePass.getTextureNode( 'emissive' );

  const bloomPass = bloom( emissivePass, 2.5, .5 );

  const fxaaPass = fxaa( outputPassFAXX );
  postProcess = new PostProcessing(renderer)
  // postProcess.outputNode = outputPass.add( bloomPass ).add( outlinePulse)  //
  postProcess.outputNode = fxaaPass.add( bloomPass ).add( outlinePulse)

}

const animate = () => {
  // renderer.renderAsync(scene, camera)
  postProcess.renderAsync()
}
</script>
<style lang="scss"></style>
